package com.isdepci.framework.web.exception;

import com.isdepci.common.constant.ErrorStatus;
import com.isdepci.common.constant.HttpStatus;
import com.isdepci.common.exception.BaseException;
import com.isdepci.common.exception.CustomException;
import com.isdepci.common.exception.DemoModeException;
import com.isdepci.common.utils.StringUtils;
import com.isdepci.framework.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.FileNotFoundException;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;

/**
 * 全局异常处理器
 *
 *
 */
@RestControllerAdvice
public class GlobalExceptionHandler
{
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 基础异常
     */
    @ExceptionHandler(BaseException.class)
    public AjaxResult baseException(BaseException e){
        return AjaxResult.error(e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(CustomException.class)
    public AjaxResult businessException(CustomException e)
    {
        if (StringUtils.isNull(e.getCode()))
        {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public AjaxResult handlerNoFoundException(Exception e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(HttpStatus.NOT_FOUND, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(AccessDeniedException.class)
    public AjaxResult handleAuthorizationException(AccessDeniedException e) {
        log.error(e.getMessage());
        return AjaxResult.error(HttpStatus.FORBIDDEN, "没有权限，请联系管理员授权");
    }

    @ExceptionHandler(AccountExpiredException.class)
    public AjaxResult handleAccountExpiredException(AccountExpiredException e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(e.getMessage());
    }

    @ExceptionHandler(UsernameNotFoundException.class)
    public AjaxResult handleUsernameNotFoundException(UsernameNotFoundException e)
    {
        log.error(e.getMessage(), e);
        return AjaxResult.error(e.getMessage());
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(BindException.class)
    public AjaxResult validatedBindException(BindException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getAllErrors().get(0).getDefaultMessage();
        return AjaxResult.error(message);
    }

    /**
     * 自定义验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object validExceptionHandler(MethodArgumentNotValidException e)
    {
        log.error(e.getMessage(), e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return AjaxResult.error(message);
    }

    /**
     * 演示模式异常
     */
    @ExceptionHandler(DemoModeException.class)
    public AjaxResult demoModeException(DemoModeException e)
    {
        return AjaxResult.error("演示模式，不允许操作");
    }

    /**
     * 数据格式转换错误 ClassCastException
     */
    @ExceptionHandler(ClassCastException.class)
    public AjaxResult classCastException(Exception e){
        log.error(e.getMessage());
        return AjaxResult.error(ErrorStatus.CLASS_CAST_EXCEPTION, null);
    }

    /**
     * SQL执行错误  SQLException
     */
    @ExceptionHandler(SQLException.class)
    public AjaxResult sqlException(Exception e){
        log.error(e.getMessage());
        return AjaxResult.error(ErrorStatus.SQL_EXCEPTION, null);
    }

    /**
     * NULL值 NullPointerException
     */
//    @ExceptionHandler(NullPointerException.class)
//    public AjaxResult nullPointerException(Exception e){
//        log.error(e.getMessage());
//        return AjaxResult.error(ErrorStatus.NULL_POINTER_EXCEPTION, null);
//    }

    /**
     * 文件读取失败，请检查路径  FileNotFoundException
     */
    @ExceptionHandler(FileNotFoundException.class)
    public AjaxResult fileNotFoundException(Exception e){
        log.error(e.getMessage());
        return AjaxResult.error(ErrorStatus.FILE_NOT_FOUND_EXCEPTION, null);
    }
    /**
     *  连接被拒绝
     */
    @ExceptionHandler(ConnectException.class)
    public AjaxResult ConnectException(ConnectException e){
        log.error(e.getMessage());
        return AjaxResult.error(ErrorStatus.CONNECT_EXCEPTION, "错误码:"+ErrorStatus.CONNECT_EXCEPTION);
    }

    /**
     * 没有到主机的路由
     */
    @ExceptionHandler(NoRouteToHostException.class)
    public AjaxResult NoRouteToHostException(NoRouteToHostException e){
        log.error(e.getMessage());
        return AjaxResult.error(ErrorStatus.NO_ROUTE_TO_HOST_EXCEPTION, "错误码:"+ErrorStatus.NO_ROUTE_TO_HOST_EXCEPTION);
    }

    @ExceptionHandler(Exception.class)
    public AjaxResult handleException(Exception e){
        log.error(e.getMessage(), e);
        final Throwable cause = e.getCause();
        //数据库字段异常
        if (cause instanceof SQLSyntaxErrorException) {
            return  AjaxResult.error(ErrorStatus.SQL_SYNTAX_ERROR,"错误码:"+ ErrorStatus.SQL_SYNTAX_ERROR);
        }
        //SQL执行错误
        if (cause instanceof SQLException) {
            return  AjaxResult.error(ErrorStatus.SQL_EXCEPTION,"错误码:"+ ErrorStatus.SQL_EXCEPTION);
        }
        return AjaxResult.error("错误码:"+ErrorStatus.EXCEPTION);
    }


}
